package com.example.filesftp.ftptransfer.util;

import com.example.common.core.util.R;
import com.example.filesftp.ftptransfer.domain.entity.FileTransferConfig;
import com.mchange.v2.lang.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.springframework.stereotype.Component;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Stack;
import java.util.regex.Pattern;

@Slf4j
@Component
public class FtpUtilbak {
    // 设置FTP服务器字符编码（解决中文乱码问题）
    private static final String GBK_ENCODING = "GBK";
    private static final String UTF_8_ENCODING = "UTF-8";

    // 断点续传相关常量
    private static final int BUFFER_SIZE = 8192;
    private static final int MAX_RETRIES = 3;
    private static final long RETRY_DELAY_MS = 2000;
    private static final long PROGRESS_LOG_INTERVAL_MS = 5000;

    /**
     * FTP下载文件（支持断点续传）
     */
    public R ftpDownloadFile(FileTransferConfig config, LocalDate date) throws IOException {
        // 将日期转换为第二天0点的起报时间
        LocalDateTime publishTime = date.plusDays(1).atStartOfDay();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHH");
        String publishTimeStr = publishTime.format(formatter);

        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        String createTimeStr = date.format(dateTimeFormatter);

        String csvFileName = config.getCsvFileName();
        String designateFileName = config.getFileName();

        String dynamicPattern = null;
        Pattern filePattern = null;

        if (StringUtils.nonEmptyString(designateFileName)) {
            dynamicPattern = designateFileName;
            filePattern = Pattern.compile(dynamicPattern);
        }

        if (StringUtils.nonEmptyString(csvFileName)) {
            dynamicPattern = csvFileName
                    .replace("(?<time>\\d{8})", createTimeStr)
                    .replace("(?<date>\\d{10})", publishTimeStr);
            filePattern = Pattern.compile(dynamicPattern);
        }

        boolean isRemoteWindows = "1".equals(config.getRemoteType());
        boolean isLocalWindows = "1".equals(config.getLocalType());

        String remotePath = PathUtils.toRemotePath(config.getRemotePath(), isRemoteWindows);
        String localPath = PathUtils.toLocalPath(config.getLocalPath(), isLocalWindows);

        Path localDirPath = Paths.get(localPath);
        if (!Files.exists(localDirPath)) {
            try {
                Files.createDirectories(localDirPath);
            } catch (IOException e) {
                log.error("创建本地目录失败: {}", localDirPath, e);
                return R.failed("创建本地目录失败");
            }
        }

        FTPClient ftpClient = null;
        try {
            ftpClient = new FTPClient();
            ftpClient.setConnectTimeout(300000);
            ftpClient.setDataTimeout(120000);
            ftpClient.setDefaultTimeout(120000);

            ftpClient.connect(config.getHost(), config.getPort());
            if (!ftpClient.login(config.getUsername(), config.getPassword())) {
                return R.failed("FTP登录失败");
            }

            ftpClient.enterLocalPassiveMode();
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            String serverType = ftpClient.getSystemType();
            log.info("FTP服务器类型: {}", serverType);

            String remoteEncodeType = null;
            String localEncodeType = System.getProperty("sun.jnu.encoding");

            if (serverType.toUpperCase().contains("WINDOWS")) {
                ftpClient.setControlEncoding(GBK_ENCODING);
                remoteEncodeType = GBK_ENCODING;
            } else {
                ftpClient.setControlEncoding(UTF_8_ENCODING);
                remoteEncodeType = UTF_8_ENCODING;
            }

            String encodedRemotePath = new String(remotePath.getBytes(remoteEncodeType), localEncodeType);
            log.info("获取路径: {}",encodedRemotePath);
            if (StringUtils.nonEmptyString(dynamicPattern)) {
                encodedRemotePath = encodedRemotePath + dynamicPattern;
            }
            log.info("开始下载: {}",encodedRemotePath);
            if (isRemoteFile(ftpClient, encodedRemotePath)) {
                log.info("单文件: {}",encodedRemotePath);
                if (!shouldSkipDownload(ftpClient, encodedRemotePath, localDirPath, remoteEncodeType, localEncodeType)) {
                    downloadSingleFileWithResume(ftpClient, encodedRemotePath, localDirPath, remoteEncodeType, localEncodeType, config);
                } else {
                    log.info("文件已存在且相同，跳过下载: {}", encodedRemotePath);
                }
            } else {
                log.info("下载目录: {}",encodedRemotePath);
                downloadDirectoryWithResume(ftpClient, encodedRemotePath, localDirPath, remoteEncodeType, localEncodeType, config);
            }
        } catch (Exception ex) {
            log.error(ex.getLocalizedMessage(), ex);
            return R.failed("FTP操作失败: " + ex.getMessage());
        } finally {
            try {
                if (ftpClient != null && ftpClient.isConnected()) {
                    ftpClient.logout();
                    ftpClient.disconnect();
                }
            } catch (Exception e) {
                log.error(e.getLocalizedMessage(), e);
            }
        }
        return R.ok("执行成功");
    }

    /**
     * 支持断点续传的单个文件下载
     */
    private void downloadSingleFileWithResume(FTPClient ftpClient, String remoteFilePath,
                                              Path localDirPath, String remoteEncoding,
                                              String localEncoding, FileTransferConfig config) throws IOException {
        String fileName = new File(remoteFilePath).getName();
        String correctFileName = new String(fileName.getBytes(remoteEncoding), localEncoding);
        Path localFilePath = localDirPath.resolve(correctFileName);

        log.info("开始下载文件(支持断点续传): {} → {}", remoteFilePath, localFilePath);

        FTPFile[] remoteFiles = ftpClient.listFiles(remoteFilePath);
        if (remoteFiles.length == 0) {
            throw new FileNotFoundException("远程文件不存在: " + remoteFilePath);
        }

        FTPFile remoteFile = remoteFiles[0];
        long remoteFileSize = remoteFile.getSize();
        long localFileSize = 0;

        boolean resume = false;
        if (Files.exists(localFilePath)) {
            localFileSize = Files.size(localFilePath);
            if (localFileSize < remoteFileSize) {
                resume = true;
                log.info("发现未完成下载，启用断点续传。已下载: {}/{} bytes", localFileSize, remoteFileSize);
            } else if (localFileSize == remoteFileSize) {
                log.info("文件已完整下载，跳过下载: {}", correctFileName);
                return;
            }
        }

        for (int attempt = 1; attempt <= MAX_RETRIES; attempt++) {
            try {
                if (resume) {
                    downloadWithResume(ftpClient, remoteFilePath, localFilePath.toFile(),
                            localFileSize, remoteFileSize);
                } else {
                    downloadFullFile(ftpClient, remoteFilePath, localFilePath.toFile(), remoteFileSize);
                }
                log.info("文件下载成功: {}", correctFileName);
                break;
            } catch (IOException e) {
                if (attempt == MAX_RETRIES) {
                    throw new IOException("文件下载失败，达到最大重试次数: " + correctFileName, e);
                }
                log.warn("下载尝试 {} 失败，{}秒后重试: {}", attempt, RETRY_DELAY_MS / 1000, e.getMessage());
                try {
                    Thread.sleep(RETRY_DELAY_MS);
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    throw new IOException("下载被中断", ie);
                }

                if (!ftpClient.isConnected()) {
                    reconnectFTPClient(ftpClient, config);
                }
            }
        }
    }

    /**
     * 断点续传下载
     */
    private void downloadWithResume(FTPClient ftpClient, String remoteFilePath,
                                    File localFile, long localFileSize, long remoteFileSize)
            throws IOException {

        try (RandomAccessFile outputFile = new RandomAccessFile(localFile, "rw");
             InputStream inputStream = ftpClient.retrieveFileStream(remoteFilePath)) {

            if (inputStream == null) {
                throw new IOException("无法获取文件流: " + ftpClient.getReplyString());
            }

            long skipped = inputStream.skip(localFileSize);
            if (skipped != localFileSize) {
                throw new IOException("跳过已下载部分失败，期望跳过: " + localFileSize + ", 实际跳过: " + skipped);
            }

            outputFile.seek(localFileSize);

            byte[] buffer = new byte[BUFFER_SIZE];
            int bytesRead;
            long totalBytesRead = localFileSize;
            long lastLogTime = System.currentTimeMillis();

            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputFile.write(buffer, 0, bytesRead);
                totalBytesRead += bytesRead;

                long currentTime = System.currentTimeMillis();
                if (currentTime - lastLogTime > PROGRESS_LOG_INTERVAL_MS) {
                    double progress = (double) totalBytesRead / remoteFileSize * 100;
                    log.info("下载进度: {}/{} bytes ({}%)",
                            totalBytesRead, remoteFileSize, progress);
                    lastLogTime = currentTime;
                }
            }

            if (totalBytesRead != remoteFileSize) {
                throw new IOException("文件下载不完整，期望: " + remoteFileSize +
                        ", 实际: " + totalBytesRead + " bytes");
            }

            if (!ftpClient.completePendingCommand()) {
                throw new IOException("无法完成待处理命令: " + ftpClient.getReplyString());
            }

        } finally {
            try {
                ftpClient.completePendingCommand();
            } catch (Exception e) {
                log.warn("重置连接状态时发生警告: {}", e.getMessage());
            }
        }
    }

    /**
     * 完整文件下载
     */
    private void downloadFullFile(FTPClient ftpClient, String remoteFilePath, File localFile, long remoteFileSize)
            throws IOException {

        try (OutputStream outputStream = new FileOutputStream(localFile);
             InputStream inputStream = ftpClient.retrieveFileStream(remoteFilePath)) {

            if (inputStream == null) {
                throw new IOException("无法获取文件流: " + ftpClient.getReplyString());
            }

            byte[] buffer = new byte[BUFFER_SIZE];
            int bytesRead;
            long totalBytesRead = 0;
            long lastLogTime = System.currentTimeMillis();

            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
                totalBytesRead += bytesRead;

                long currentTime = System.currentTimeMillis();
                if (currentTime - lastLogTime > PROGRESS_LOG_INTERVAL_MS) {
                    double progress = (double) totalBytesRead / remoteFileSize * 100;
                    log.info("下载进度: {}/{} bytes ({}%)", totalBytesRead, remoteFileSize, progress);
                    lastLogTime = currentTime;
                }
            }

            if (!ftpClient.completePendingCommand()) {
                throw new IOException("无法完成待处理命令: " + ftpClient.getReplyString());
            }

        } finally {
            try {
                ftpClient.completePendingCommand();
            } catch (Exception e) {
                log.warn("重置连接状态时发生警告: {}", e.getMessage());
            }
        }
    }

    /**
     * 支持断点续传的目录下载
     */
    private void downloadDirectoryWithResume(FTPClient ftpClient, String remoteDirPath,
                                             Path localDirPath, String remoteEncoding,
                                             String localEncoding, FileTransferConfig config) throws IOException {
        if (!Files.exists(localDirPath)) {
            Files.createDirectories(localDirPath);
        }

        String workingDir = ftpClient.printWorkingDirectory();
        log.info("当前工作目录: " + workingDir);

        FTPFile[] filesInCurrentDir = ftpClient.listFiles();
        log.info("当前目录文件数: " + filesInCurrentDir.length);

        int list = ftpClient.list(remoteDirPath);
        log.info("目录文件数: " + list);
        ftpClient.changeWorkingDirectory(remoteDirPath);
        log.info("切换到目录: " + remoteDirPath);
//        String[] fileNames = ftpClient.listNames(remoteDirPath);
//        if (fileNames != null) {
//            log.info("找到 " + fileNames.length + " 个文件：");
//            for (String name : fileNames) {
//                log.info(" - name:" + name);
//            }
//        }

        FTPFile[] remoteFiles = ftpClient.listFiles(remoteDirPath);
        log.info("处理目录: {}", remoteDirPath);
        log.info("目录下文件数量: {}", remoteFiles.length);
        for (FTPFile remoteFile : remoteFiles) {
            if (remoteFile.getName().equals(".") || remoteFile.getName().equals("..")) {
                continue;
            }

            String correctFileName = new String(remoteFile.getName().getBytes(remoteEncoding), localEncoding);
            String childRemotePath = remoteDirPath + "/" + remoteFile.getName();
            Path childLocalPath = localDirPath.resolve(correctFileName);

            if (remoteFile.isDirectory()) {
                log.info("处理子目录: {}", correctFileName);
                downloadDirectoryWithResume(ftpClient, childRemotePath, childLocalPath,
                        remoteEncoding, localEncoding, config);
            } else {
                if (!shouldSkipDownload(ftpClient, childRemotePath, localDirPath, remoteEncoding, localEncoding)) {
                    downloadSingleFileWithResume(ftpClient, childRemotePath, localDirPath,
                            remoteEncoding, localEncoding, config);
                } else {
                    log.info("文件已存在且相同，跳过下载: {}", correctFileName);
                }
            }
        }
    }

    /**
     * 重新连接FTP客户端
     */
    private void reconnectFTPClient(FTPClient ftpClient, FileTransferConfig config) throws IOException {
        try {
            if (ftpClient.isConnected()) {
                ftpClient.disconnect();
            }

            ftpClient.setConnectTimeout(30000);
            ftpClient.setDataTimeout(120000);
            ftpClient.setDefaultTimeout(120000);

            ftpClient.connect(config.getHost(), config.getPort());
            if (!ftpClient.login(config.getUsername(), config.getPassword())) {
                throw new IOException("FTP重新登录失败");
            }

            ftpClient.enterLocalPassiveMode();
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

            log.info("FTP客户端重新连接成功");

        } catch (IOException e) {
            throw new IOException("FTP重新连接失败: " + e.getMessage(), e);
        }
    }

    /**
     * 增强的文件查重检查（支持断点续传）
     */
    private boolean shouldSkipDownload(FTPClient ftpClient, String remoteFilePath, Path localDirPath,
                                       String remoteEncoding, String localEncoding) throws IOException {
        FTPFile[] remoteFiles = ftpClient.listFiles(remoteFilePath);
        if (remoteFiles.length == 0) {
            return false;
        }

        FTPFile remoteFile = remoteFiles[0];
        String fileName = new File(remoteFilePath).getName();
        String correctFileName = new String(fileName.getBytes(remoteEncoding), localEncoding);
        Path localFilePath = localDirPath.resolve(correctFileName);

        if (!Files.exists(localFilePath)) {
            return false;
        }

        BasicFileAttributes localAttrs = Files.readAttributes(localFilePath, BasicFileAttributes.class);
        long localFileSize = localAttrs.size();
        long remoteFileSize = remoteFile.getSize();

        if (localFileSize < remoteFileSize) {
            log.info("发现未完成下载，需要断点续传: {}/{} bytes", localFileSize, remoteFileSize);
            return false;
        }

        if (localFileSize != remoteFileSize) {
            return false;
        }

        long localModified = localAttrs.lastModifiedTime().toMillis();
        long remoteModified = remoteFile.getTimestamp().getTimeInMillis();
        if (Math.abs(localModified - remoteModified) > 1000) {
            return false;
        }

        return true;
    }

    /**
     * FTP上传文件
     */
    public R ftpUploadFile(FileTransferConfig config, LocalDate date) throws IOException {
        LocalDateTime publishTime = date.plusDays(1).atStartOfDay();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHH");
        String publishTimeStr = publishTime.format(formatter);

        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        String createTimeStr = date.format(dateTimeFormatter);

        String csvFileName = config.getCsvFileName();
        String designateFileName = config.getFileName();

        boolean isRemoteWindows = "1".equals(config.getRemoteType());
        boolean isLocalWindows = "1".equals(config.getLocalType());

        FTPClient ftpClient = null;
        try {
            ftpClient = new FTPClient();
            ftpClient.connect(config.getHost(), config.getPort());
            if (!ftpClient.login(config.getUsername(), config.getPassword())) {
                return R.failed("FTP登录失败");
            }

            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();

            String remoteEncodeType = null;
            String localEncodeType = System.getProperty("sun.jnu.encoding");

            try {
                String serverType = ftpClient.getSystemType();
                log.info("FTP服务器类型: {}", serverType);

                if (serverType.toUpperCase().contains("WINDOWS")) {
                    ftpClient.setControlEncoding(GBK_ENCODING);
                    remoteEncodeType = GBK_ENCODING;
                } else {
                    ftpClient.setControlEncoding(UTF_8_ENCODING);
                    remoteEncodeType = UTF_8_ENCODING;
                }
            } catch (Exception e) {
                log.error(e.getLocalizedMessage(), e);
                throw new IOException(e.getLocalizedMessage());
            }

            ftpClient.enterLocalPassiveMode();
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

            String localPath = PathUtils.toLocalPath(config.getLocalPath(), isLocalWindows);
            String remoteBaseDir = config.getRemotePath();

            createRemoteDir(ftpClient, remoteBaseDir, isRemoteWindows);

            if (StringUtils.nonEmptyString(designateFileName)) {
                localPath = localPath + File.separator + designateFileName;
            } else if (StringUtils.nonEmptyString(csvFileName)) {
                localPath = localPath + File.separator +
                        csvFileName.replace("${publishTime}", publishTimeStr)
                                .replace("${createTime}", createTimeStr);
            }

            File localFile = new File(localPath);
            if (localFile.isFile()) {
                String encodedRemoteDir = new String(remoteBaseDir.getBytes(localEncodeType), remoteEncodeType);
                String encodedFileName = new String(localFile.getName().getBytes(localEncodeType), remoteEncodeType);
                uploadFile(ftpClient, encodedRemoteDir, localFile, encodedFileName, remoteEncodeType, localEncodeType);
            } else if (localFile.isDirectory()) {
                String encodedRemoteDir = new String(remoteBaseDir.getBytes(localEncodeType), remoteEncodeType);
                uploadDirectory(ftpClient, encodedRemoteDir, localFile, isRemoteWindows, remoteEncodeType, localEncodeType);
            } else {
                log.error("本地路径既不是文件也不是目录: {}", localPath);
                return R.failed("无效的本地路径");
            }
        } catch (Exception e) {
            log.error("FTP操作出错: " + e.getMessage(), e);
            return R.failed("FTP操作失败");
        } finally {
            try {
                if (ftpClient != null && ftpClient.isConnected()) {
                    ftpClient.logout();
                    ftpClient.disconnect();
                }
            } catch (IOException e) {
                log.error(e.getLocalizedMessage(), e);
            }
        }
        return R.ok("执行成功");
    }

    /**
     * 递归创建远程目录
     */
    private static void createRemoteDir(FTPClient ftpClient, String remoteDir, boolean isRemoteWindows)
            throws IOException {
        String[] folders = remoteDir.split("/");
        StringBuilder pathBuilder = new StringBuilder();

        if (remoteDir.startsWith("/")) {
            pathBuilder.append("/");
        }

        for (String folder : folders) {
            if (folder.isEmpty()) {
                continue;
            }
            pathBuilder.append("/").append(folder);
            String currentPath = pathBuilder.toString();

            try {
                if (!ftpClient.changeWorkingDirectory(currentPath)) {
                    if (!ftpClient.makeDirectory(currentPath)) {
                        throw new IOException("创建目录失败: " + currentPath +
                                "，服务器返回: " + ftpClient.getReplyString());
                    }
                    log.info("创建远程目录: {}", currentPath);
                }
            } catch (IOException e) {
                log.error("目录操作失败: {}", currentPath, e);
                throw e;
            }
        }
    }

    /**
     * 上传单个文件
     */
    private static void uploadFile(FTPClient ftpClient, String remoteDir, File localFile, String encodedFileName,
                                   String remoteEncodeType, String localEncodeType)
            throws IOException {
        String remoteFilePath = remoteDir + "/" + encodedFileName;

        FTPFile[] remoteFiles = ftpClient.listFiles(remoteFilePath);
        if (remoteFiles.length > 0) {
            FTPFile remoteFile = remoteFiles[0];
            long localFileModifiedTime = localFile.lastModified();
            long remoteFileModifiedTime = remoteFile.getTimestamp().getTimeInMillis();

            if (localFileModifiedTime <= remoteFileModifiedTime) {
                String correctFileName = new String(encodedFileName.getBytes(localEncodeType), remoteEncodeType);
                log.info("文件已存在或未修改，跳过上传: {}", correctFileName);
                return;
            }
        }

        String correctFileName = new String(encodedFileName.getBytes(localEncodeType), remoteEncodeType);
        log.info("上传文件: {} -> {}", localFile.getPath(), correctFileName);
        try (InputStream fis = new FileInputStream(localFile)) {
            if (!ftpClient.storeFile(remoteFilePath, fis)) {
                throw new IOException("文件上传失败: " + ftpClient.getReplyString());
            }
        }
    }

    /**
     * 递归上传目录
     */
    private static void uploadDirectory(FTPClient ftpClient, String remoteBaseDir,
                                        File localDir, boolean isRemoteWindows, String remoteEncodeType, String localEncodeType) throws IOException {
        Stack<File> dirStack = new Stack<>();
        Stack<String> remoteDirStack = new Stack<>();

        dirStack.push(localDir);
        remoteDirStack.push(remoteBaseDir);

        while (!dirStack.isEmpty()) {
            File currentLocalDir = dirStack.pop();
            String currentRemoteDir = remoteDirStack.pop();

            createRemoteDir(ftpClient, currentRemoteDir, isRemoteWindows);

            String correctRemoteDir = new String(currentRemoteDir.getBytes(localEncodeType), remoteEncodeType);
            log.info("处理目录: {} → {}", currentLocalDir.getPath(), correctRemoteDir);

            File[] localFiles = currentLocalDir.listFiles();
            if (localFiles == null) {
                continue;
            }

            for (File file : localFiles) {
                String encodedFileName = new String(file.getName().getBytes(localEncodeType), remoteEncodeType);
                String remoteFilePath = currentRemoteDir + "/" + encodedFileName;

                if (file.isDirectory()) {
                    dirStack.push(file);
                    remoteDirStack.push(remoteFilePath);
                } else {
                    uploadFile(ftpClient, currentRemoteDir, file, encodedFileName, remoteEncodeType, localEncodeType);
                }
            }
        }
    }

    /**
     * 判断远程路径是否是文件
     */
    private boolean isRemoteFile(FTPClient ftpClient, String remotePath) throws IOException {
        String originalWorkingDir = ftpClient.printWorkingDirectory();
        log.info("开始判定是否为文件：{}",originalWorkingDir);
        try {
            if (ftpClient.changeWorkingDirectory(remotePath)) {
                ftpClient.changeWorkingDirectory(originalWorkingDir);
                return false;
            }

            String currentWorkingDir = ftpClient.printWorkingDirectory();
            log.info("当前FTP工作目录: " + currentWorkingDir);

            FTPFile[] files = ftpClient.listFiles(remotePath);
            log.info("文件大小：{}",files.length);
            if (files.length == 0) {
                log.info("远程路径不存在：{}",remotePath);
                throw new FileNotFoundException("远程路径不存在: " + remotePath);
            }

            if (files.length == 1) {
                String listedName = files[0].getName();
                String pathName = new File(remotePath).getName();

                if (listedName.equals(pathName) ||
                        files[0].getName().equalsIgnoreCase(pathName)) {
                    return !files[0].isDirectory();
                }
            }

            try {
                if (ftpClient.listFiles(remotePath + "/").length > 0) {
                    return false;
                }

                InputStream is = ftpClient.retrieveFileStream(remotePath);
                if (is != null) {
                    is.close();
                    if (!ftpClient.completePendingCommand()) {
                        throw new IOException("无法完成待处理命令");
                    }
                    return true;
                }
            } catch (IOException e) {
                return false;
            }

            return true;
        } finally {
            if (originalWorkingDir != null) {
                try {
                    ftpClient.changeWorkingDirectory(originalWorkingDir);
                } catch (IOException e) {
                    log.error("无法恢复工作目录: {}", originalWorkingDir, e);
                }
            }
        }
    }

    /**
     * 计算远程目录大小
     */
    private static long getFolderSize(FTPClient ftpClient, String remotePath) throws IOException {
        long size = 0;
        FTPFile[] files = ftpClient.listFiles(remotePath);

        for (FTPFile file : files) {
            if (file.isDirectory()) {
                if (!file.getName().equals(".") && !file.getName().equals("..")) {
                    size += getFolderSize(ftpClient, remotePath + "/" + file.getName());
                }
            } else {
                size += file.getSize();
            }
        }
        return size;
    }

//    public List<FTPFile> parseRawList(FTPClient ftpClient, String remotePath) {
//        List<FTPFile> result = new ArrayList<>();
//
//        try {
//            // 发送 LIST 命令并获取原始响应
//            try (InputStream listStream = ftpClient.retrieveFileStream(remotePath)) {
//                if (listStream != null) {
//                    BufferedReader reader = new BufferedReader(new InputStreamReader(listStream));
//                    String line;
//
//                    while ((line = reader.readLine()) != null) {
//                        try {
//                            // 尝试使用FTP客户端自带的解析器
//                            FTPFile file = ftpClient.getParser().parseFTPEntry(line);
//                            if (file != null && file.getName() != null &&
//                                    !file.getName().equals(".") && !file.getName().equals("..")) {
//                                result.add(file);
//                            }
//                        } catch (Exception e) {
//                            // 解析失败，创建基本文件对象
//                            System.out.println("解析失败的行: " + line);
//                            FTPFile basicFile = createBasicFileFromLine(line);
//                            if (basicFile != null) {
//                                result.add(basicFile);
//                            }
//                        }
//                    }
//                }
//            }
//
//        } catch (Exception e) {
//            System.out.println("解析原始列表失败: " + e.getMessage());
//        }
//
//        return result;
//    }
}